D:\git\skunkworks\herald-for-cpp\herald\src\payload\simple\k.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2021 Herald Project Contributors |
2 | | // SPDX-License-Identifier: Apache-2.0 |
3 | | // |
4 | | |
5 | | #include "herald/payload/simple/k.h" |
6 | | #include "herald/payload/simple/f.h" |
7 | | #include "herald/payload/simple/secret_key.h" |
8 | | #include "herald/payload/simple/matching_key.h" |
9 | | #include "herald/payload/simple/matching_key_seed.h" |
10 | | #include "herald/payload/simple/contact_key.h" |
11 | | #include "herald/payload/simple/contact_key_seed.h" |
12 | | #include "herald/payload/simple/contact_identifier.h" |
13 | | #include "herald/datatype/data.h" |
14 | | #include "herald/datatype/time_interval.h" |
15 | | |
16 | | namespace herald { |
17 | | namespace payload { |
18 | | namespace simple { |
19 | | |
20 | | using namespace herald::datatype; |
21 | | |
22 | | K::K() noexcept |
23 | | : keyLength(2048),daysFor(2000),periodsInDay(240), epoch(K::getEpoch()) |
24 | 0 | { |
25 | 0 | ; |
26 | 0 | } |
27 | | |
28 | | K::K(const K& other) noexcept |
29 | | : keyLength(other.keyLength), |
30 | | daysFor(other.daysFor), |
31 | | periodsInDay(other.periodsInDay), |
32 | | epoch(other.epoch) |
33 | 0 | { |
34 | 0 | ; |
35 | 0 | } |
36 | | |
37 | | K::K(int keyLength, int daysFor, int periodsInDay) noexcept |
38 | | : keyLength(keyLength),daysFor(daysFor),periodsInDay(periodsInDay), epoch(K::getEpoch()) |
39 | 0 | { |
40 | 0 | ; |
41 | 0 | } |
42 | | |
43 | | K::K(int keyLength, int daysFor, int periodsInDay, TimeInterval epochBeginning) noexcept |
44 | | : keyLength(keyLength),daysFor(daysFor),periodsInDay(periodsInDay), epoch(epochBeginning) |
45 | 0 | { |
46 | 0 | ; |
47 | 0 | } |
48 | | |
49 | 0 | K::~K() noexcept = default; |
50 | | |
51 | | TimeInterval |
52 | 0 | K::getEpoch() noexcept { |
53 | 0 | return TimeInterval(0); // Jan 1st 1970, seconds |
54 | 0 | } |
55 | | |
56 | | int |
57 | 0 | K::day(Date on) const noexcept { |
58 | 0 | return (long)(on - epoch) / 86400; |
59 | 0 | } |
60 | | |
61 | | int |
62 | 0 | K::period(Date at) const noexcept { |
63 | 0 | long seconds = (long)(at - epoch) % 86400; |
64 | 0 | return (seconds * periodsInDay) / 86400; // more accurate |
65 | 0 | } |
66 | | |
67 | | /// Low memory version of the key generator - generates key for a specified day |
68 | | /// This saves memory use on Zephyr at the cost of CPU utilisation |
69 | | MatchingKey |
70 | 0 | K::matchingKey(const SecretKey& secretKey, const int dayIdxFor) noexcept { |
71 | 0 | // lazy initialisation |
72 | 0 | MatchingKeySeed last(F::h(secretKey)); // value for day 2000 |
73 | 0 | MatchingKeySeed newSeed(32); |
74 | 0 | for (int i = daysFor - 1;i >= dayIdxFor; --i) { |
75 | 0 | // Calculate 1999 based on 2000, and so on, until we reach the current day's seed |
76 | 0 | newSeed.assign(F::h(F::t(last))); |
77 | 0 | last.assign(newSeed); |
78 | 0 | } |
79 | 0 | // At this point newSeed is the same as last, and last holds the seed for day dayIdxFor |
80 | 0 | |
81 | 0 | // matching key on day 0 is derived from matching key seed on day dayIdxFor and day dayIdxFor-1 |
82 | 0 | MatchingKeySeed minusOne(F::h(F::t(last))); |
83 | 0 |
|
84 | 0 | return MatchingKey(F::h(F::xorData(last,minusOne))); |
85 | 0 | } |
86 | | |
87 | | |
88 | | |
89 | | ContactKey |
90 | 0 | K::contactKey(const SecretKey& secretKey, const int dayFor, const int periodFor) noexcept { |
91 | 0 | const int n = periodsInDay; |
92 | 0 |
|
93 | 0 | auto mk(matchingKey(secretKey,dayFor)); |
94 | 0 |
|
95 | 0 | ContactKeySeed last(F::h(mk)); |
96 | 0 | ContactKeySeed lastMinusOne(32); |
97 | 0 | for (int j = n - 1;j >= periodFor;j--) { |
98 | 0 | lastMinusOne.assign(F::h(F::t(last))); |
99 | 0 | last.assign(lastMinusOne); |
100 | 0 | } |
101 | 0 | // we now have lastMinusOne = contactKeySeed at periodFor |
102 | 0 |
|
103 | 0 | // Day 0 key now |
104 | 0 | ContactKeySeed minusOne(F::h(F::t(last))); |
105 | 0 |
|
106 | 0 | return ContactKey(F::h(F::xorData(last, minusOne))); |
107 | 0 | } |
108 | | |
109 | | ContactIdentifier |
110 | 0 | K::contactIdentifier(const SecretKey& secretKey, const int dayFor,const int periodFor) noexcept { |
111 | 0 | auto ck(contactKey(secretKey,dayFor,periodFor)); |
112 | 0 | return ContactIdentifier(F::t(ck, 16)); |
113 | 0 | } |
114 | | |
115 | | // NOTE I'm keeping the old functions here in case we need to use a caching version on another platform |
116 | | |
117 | | // const std::vector<MatchingKey>& |
118 | | // K::matchingKeys(const SecretKey& secretKey) noexcept { |
119 | | // if (0 == mImpl->matchingKeySet.size()) { |
120 | | // // lazy initialisation |
121 | | // std::vector<MatchingKeySeed> matchingKeySeed(mImpl->daysFor + 1); |
122 | | // matchingKeySeed.reserve(mImpl->daysFor + 1); |
123 | | // matchingKeySeed[mImpl->daysFor] = MatchingKeySeed(F::h(secretKey)); |
124 | | // for (int i = mImpl->daysFor - 1;i >=0; i--) { |
125 | | // matchingKeySeed[i].append(F::h(F::t(matchingKeySeed[i + 1]))); |
126 | | // } |
127 | | |
128 | | // mImpl->matchingKeySet.reserve(mImpl->daysFor + 1); |
129 | | // for (int i = 0;i <= mImpl->daysFor;i++) { |
130 | | // mImpl->matchingKeySet.emplace_back(); |
131 | | // } |
132 | | |
133 | | // // matching key on day 0 is derived from matching key seed on day 0 and day -1 |
134 | | // MatchingKeySeed minusOne(F::h(F::t(matchingKeySeed[0]))); |
135 | | // mImpl->matchingKeySet[0].append(F::h(F::xorData(matchingKeySeed[0],minusOne))); |
136 | | |
137 | | // // Matching key for day i is the hash of the matching key seed for day i xor i-1 |
138 | | // for (int i = 1; i <= mImpl->daysFor;i++) { |
139 | | // mImpl->matchingKeySet[i].append(F::h(F::xorData(matchingKeySeed[i], matchingKeySeed[i - 1]))); |
140 | | // } |
141 | | // // TODO set sk hash in this class to cache result |
142 | | // } else { |
143 | | // // TODO verify that the hash of the sk is the same as before |
144 | | // } |
145 | | // return mImpl->matchingKeySet; |
146 | | // } |
147 | | |
148 | | // const std::vector<ContactKey> |
149 | | // K::contactKeys(const MatchingKey& matchingKey) noexcept { |
150 | | // const int n = mImpl->periodsInDay; |
151 | | |
152 | | // std::vector<ContactKeySeed> contactKeySeed; |
153 | | // contactKeySeed.reserve(n + 1); |
154 | | |
155 | | // for (int i = 0;i <= n;i++) { |
156 | | // contactKeySeed.emplace_back(); |
157 | | // } |
158 | | |
159 | | // contactKeySeed[n].append(F::h(matchingKey)); |
160 | | // for (int j = n - 1;j >= 0;j--) { |
161 | | // contactKeySeed[j].append(F::h(F::t(contactKeySeed[j + 1]))); |
162 | | // } |
163 | | |
164 | | // std::vector<ContactKey> contactKey; |
165 | | // contactKey.reserve(n + 1); |
166 | | |
167 | | // for (int i = 0;i <= n;i++) { |
168 | | // contactKey.emplace_back(); |
169 | | // } |
170 | | |
171 | | // for (int j = 1;j <= n;j++) { |
172 | | // contactKey[j].append(F::h(F::xorData(contactKeySeed[j],contactKeySeed[j - 1]))); |
173 | | // } |
174 | | |
175 | | // // Day 0 key now |
176 | | // ContactKeySeed minusOne(F::h(F::t(contactKeySeed[0]))); |
177 | | // contactKey[0].append(F::h(F::xorData(contactKeySeed[0], minusOne))); |
178 | | |
179 | | // return contactKey; |
180 | | // } |
181 | | |
182 | | // const ContactIdentifier |
183 | | // K::contactIdentifier(const ContactKey& contactKey) noexcept { |
184 | | // return ContactIdentifier(F::t(contactKey, 16)); |
185 | | // } |
186 | | |
187 | | |
188 | | } |
189 | | } |
190 | | } |